package com.sciencep.pro.admin.system.common.util;

import com.alibaba.fastjson.JSON;
import com.sciencep.pro.admin.system.common.authentication.JWTUtil;
import com.sciencep.pro.common.exception.CustomException;
import com.sciencep.pro.common.utils.HttpContextUtil;
import com.sciencep.pro.core.domain.dto.user.UserDetail;
import com.sciencep.pro.core.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.*;

import static com.sciencep.pro.admin.system.common.authentication.JWTFilter.TOKEN;
import static com.sciencep.pro.common.config.Constant.USERINFO_CACHE_PREFIX;

@Slf4j
@Component
public class UserUtil {

    private static final String HOLIDAY = "holiday";

    private UserUtil() {

    }

    @Autowired
    private RedisService redisService;


    public UserDetail getCurrentUserDetail() throws CustomException {

        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
        String token = request.getHeader(TOKEN);
        String userId = JWTUtil.getUserId(token);
        String value;
        try {
            value = redisService.get(USERINFO_CACHE_PREFIX + userId);
        } catch (Exception e) {
            log.error("redis错误{}" + e.getMessage());
            throw new CustomException("redis连接失败");
        }
        if (value == null) {
            throw new CustomException("验证失败 请重新登录");
        }
        return JSON.parseObject(value, UserDetail.class);
    }

    /**
     * 获取当月的所有工作日
     *
     * @param year
     * @param month
     * @return
     */
    public static List<String> getWorkdayInMonth(int year, int month) {
        List<String> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);// 不设置的话默认为当年
        calendar.set(Calendar.MONTH, month - 1);// 设置月份
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为当月第一天
        int daySize = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);// 当月最大天数
        for (int i = 0; i < daySize; i++) {
            String format = DateUtils.formatDate(calendar.getTime(), "yyyy-MM-dd");
            int ifHoliday = getIfHoliday(format);
            if (ifHoliday != 2) {
                int week = calendar.get(Calendar.DAY_OF_WEEK);
                //周末休息
                if ((week == Calendar.SATURDAY || week == Calendar.SUNDAY)) {// 1代表周日，7代表周六 判断这是一个星期的第几天从而判断是否是周末
                    //如果是补班，则属于正常上班时间
                    if (ifHoliday == 3) {
                        list.add(year + "-" + month + "-" + calendar.get(Calendar.DAY_OF_MONTH));
                    }
                } else {
                    // 得到当天是一个月的第几天
                    list.add(year + "-" + month + "-" + calendar.get(Calendar.DAY_OF_MONTH));
                }

            }
            calendar.add(Calendar.DATE, 1);//在第一天的基础上加1

        }
        return list;
    }

    /**
     * 判断该日期是否为节假日
     *
     * @param date 1,正常工作日  2,节假日 3,节假日后补班 4,周末
     * @return
     */
    public static int getIfHoliday(String date) {
        int flag = 1;
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
            HttpEntity<String> entity = new HttpEntity<>(headers);
            Map<String, Object> map = new HashMap<>();
            ResponseEntity<Object> response = restTemplate.exchange("http://timor.tech/api/holiday/info/" + date, HttpMethod.GET, entity, Object.class);
            if (response.hasBody()) {
                map = (Map<String, Object>) response.getBody();
                if (map == null) {
                    map = new HashMap<>();
                }
            }

            if (map.get(HOLIDAY) == null) {
                flag = 1;
            } else {
                Map<String, Object> holidayDO = (Map) map.get(HOLIDAY);
                Boolean object = (Boolean) holidayDO.get(HOLIDAY);
                if (object.equals(true)) {
                    flag = 2;//节假日
                } else {
                    flag = 3;//节假日补班
                }
            }
            LocalDate localDate = LocalDate.parse(date);
            int value = localDate.getDayOfWeek().getValue();
            if ((value == 6 || value == 7) && flag != 3) {//如果不是节假日补班情况，则返回周末
                flag = 4;//周末
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取是否工作日异常.", e);
        }
        return flag;
    }

}
